/*******************************************************************************
 *
 * Copyright (c) 2001, 2002 Boris Pruessmann and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v0.5
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors:
 *    Boris Pruessmann - Initial implementation.
 ******************************************************************************/
package net.sourceforge.perforce.ui.action;


import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;

import net.sourceforge.perforce.core.PerforceCorePlugin;
import net.sourceforge.perforce.core.PerforceException;
import net.sourceforge.perforce.core.api.IPerforceServer;
import net.sourceforge.perforce.ui.dialogs.ChangeSpecDialog;
import net.sourceforge.perforce.ui.internal.Policy;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.IAction;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.actions.WorkspaceModifyOperation;


/**
  * @version  $Revision: 82 $
  * @author   <a href="mailto:bpruessmann@users.sourceforge.net">Boris Pruessmann</a>
  */
public class NewChangelistAction extends PerforceAction 
{
	// ------------------------------------------------------------------------------ Public Methods
	
	/** @see IActionDelegate#run(org.eclipse.jface.action.IAction) */
	public void run(IAction action) 
	{
		run(new WorkspaceModifyOperation()
		{
			/** @see WorkspaceModifyOperation#execute(IProgressMonitor) */
			protected void execute(IProgressMonitor monitor)
				throws InvocationTargetException
			{
				final PerforceException[] exception = { null };
				final IPerforceServer[] servers = getSelectedServers();
				Policy.assertTrue(servers.length == 1);
								
				Display display = getShell().getDisplay(); 
				display.syncExec(new Runnable() 
				{
					public void run() 
					{
						try
						{
							ChangeSpecDialog dialog = 
								ChangeSpecDialog.newInstance(getShell(), servers[0]);
							if (dialog.open() == ChangeSpecDialog.OK)
							{
								servers[0].change(dialog.getChangeSpec());
								PerforceCorePlugin.getPlugin().broadcastChangelistStateChanges(servers);					
							}
						}
						catch (PerforceException e)
						{
							exception[0] = e;
						}										
					}
				});
				
				if (exception[0] != null)
				{
					throw new InvocationTargetException(exception[0]);
				}
			}

		}, PROGRESS_DIALOG);
	}

	// --------------------------------------------------------------------------- Protected Methods

	/** @see PerforceAction#isEnabled() */
	protected boolean isEnabled() 
		throws PerforceException 
	{
		IPerforceServer[] servers = getSelectedServers();
		if (servers.length == 1)
		{
			return true;
		}
		
		return false;
	}

	// ----------------------------------------------------------------------------- Private Methods
	
	/** Call this method to retrieve an array of selected servers.
	  *
	  * @return array of selected servers. 
 	  */
	private IPerforceServer[] getSelectedServers()
	{
		ArrayList resources = null;
		if (!getSelection().isEmpty())
		{
			resources = new ArrayList();
			for (Iterator elements = getSelection().iterator(); elements.hasNext();)
			{
				Object next = elements.next();			
				if (next instanceof IPerforceServer)
				{
					resources.add(next);
					continue;
				}
				else
				if (next instanceof IAdaptable)
				{
					IAdaptable a = (IAdaptable) next;
					Object adapter = a.getAdapter(IPerforceServer.class);
					if (adapter instanceof IPerforceServer)
					{
						resources.add(adapter);
						continue;
					}
				}
			}
		}
		
		if (resources != null && !resources.isEmpty())
		{
			return (IPerforceServer[]) resources.toArray(new IPerforceServer[resources.size()]);
		}
		
		return new IPerforceServer[0];
	}
}
